function obj = LockTransverseField(obj, varargin)
    L = log4m.getLogger;
    
    p = inputParser;
    p.addOptional('channel', 'both', @(x) ismember(x, {'x', 'y', 'both'}));
    p.parse(varargin{:});
    
    if isempty(obj.SystemInfo.WorkingPoint)
        error('No WorkingPoint found.');
    else
        wp = obj.SystemInfo.WorkingPoint; 
    end
    
    switch lower(p.Results.channel)
        case 'x'
            gainX = wp.exportScaleDC * wp.slopeX;
            orderX = obj.bTransDCx.getSetting('order');
            bwX = obj.bTransDCx.getSetting('bandwidth');
            
            s=tf('s');
            fltrX = 1/(1+ziBW2TC(bwX, orderX)*s)^orderX;
            [gmX, ~, wgmX, ~] = margin(fltrX);
            
            lockDCx = EquipmentControl.FeedBackOptimization.ZieglerNichols.getPID_ZN(gmX/gainX, 2*pi/wgmX);
            obj.SystemInfo.TransFieldLocking.Px = lockDCx.pVal;
            obj.SystemInfo.TransFieldLocking.Ix = lockDCx.iVal;
            obj.SystemInfo.TransFieldLocking.Dx = lockDCx.dVal;
            obj.SystemInfo.TransFieldLocking.DLimx = 10.0*bwX;
            obj.SystemInfo.TransFieldLocking.Ratex = 100e3;
            
            obj.ziSlave.setPIDMode('0', 0);
            obj.ziSlave.setPIDInput('0', 4);
            obj.ziSlave.setPIDInputChannel('0', 0);
            obj.ziSlave.setPIDSetpoint('0', 0.0);
            obj.ziSlave.disablePIDPhaseUnwarp('0');
            obj.ziSlave.setPIDOutput('0', 5);
            obj.ziSlave.setPIDOutputChannel('0', 0);
            obj.ziSlave.setPIDCenter('0', wp.biasX);
            obj.ziSlave.setPIDLimLower('0', -0.01);
            obj.ziSlave.setPIDLimUpper('0', 0.01);
            obj.ziSlave.setPValue('0', lockDCx.pVal);
            obj.ziSlave.setIValue('0', lockDCx.iVal);
            obj.ziSlave.setDValue('0', lockDCx.dVal);
            obj.ziSlave.setDLimValue('0', 10.0*bwX);
            obj.ziSlave.setRateValue('0', 100e3);
            obj.ziSlave.lock('0');
            L.info('LockTransverseField', sprintf('Bx is locked: Px=[%5.3e], Ix=[%5.3e], Dx=[%5.3e]', lockDCx.pVal, lockDCx.iVal, lockDCx.dVal));
            
        case 'y'
            gainY = wp.exportScaleDC * wp.slopeY;
            orderY = obj.bTransDCy.getSetting('order');
            bwY = obj.bTransDCy.getSetting('bandwidth');
            
            s=tf('s');
            fltrY = 1/(1+ziBW2TC(bwY, orderY)*s)^orderY;
            [gmY, ~, wgmY, ~] = margin(fltrY);

            lockDCy = EquipmentControl.FeedBackOptimization.ZieglerNichols.getPID_ZN(gmY/gainY, 2*pi/wgmY);
            obj.SystemInfo.TransFieldLocking.Py = lockDCy.pVal;
            obj.SystemInfo.TransFieldLocking.Iy = lockDCy.iVal;
            obj.SystemInfo.TransFieldLocking.Dy = lockDCy.dVal;
            obj.SystemInfo.TransFieldLocking.DLimy = 10.0*bwY;
            obj.SystemInfo.TransFieldLocking.Ratey = 100e3;
            
            obj.ziSlave.setPIDMode('1', 0);
            obj.ziSlave.setPIDInput('1', 4);
            obj.ziSlave.setPIDInputChannel('1', 1);
            obj.ziSlave.setPIDSetpoint('1', 0.0);
            obj.ziSlave.disablePIDPhaseUnwarp('1');
            obj.ziSlave.setPIDOutput('1', 7);
            obj.ziSlave.setPIDOutputChannel('1', 0);
            obj.ziSlave.setPIDCenter('1', wp.biasY);
            obj.ziSlave.setPIDLimLower('1', -0.01);
            obj.ziSlave.setPIDLimUpper('1', 0.01);
            obj.ziSlave.setPValue('1', lockDCy.pVal);
            obj.ziSlave.setIValue('1', lockDCy.iVal);
            obj.ziSlave.setDValue('1', lockDCy.dVal);
            obj.ziSlave.setDLimValue('1', 10.0*bwY);
            obj.ziSlave.setRateValue('1', 100e3);
            obj.ziSlave.lock('1');
            L.info('LockTransverseField', sprintf('By is locked: Py=[%5.3e], Iy=[%5.3e], Dy=[%5.3e]', lockDCy.pVal, lockDCy.iVal, lockDCy.dVal));
            
        case 'both'
            obj.LockTransverseField('x');
            obj.LockTransverseField('y');
    end   
end

% function lock = getPID_ZN(Kc, Pv)
%     tI = Pv/2.0; tD = Pv/8.0;
%     lock.pVal = Kc/1.7;
%     lock.iVal = lock.pVal/tI;
%     lock.dVal = lock.pVal*tD;    
% end

